#!/bin/bash

# SSH-LPR Backend
# Based on http://www.masella.name/technical/sshlpr.html

# The purpose of the back end is to send print jobs to a remote system
# through ssh and lpr on the remote side. It requires that the lp user
# have a key-based authentication set up for the server in
# question. The printer URI is sshlpr://ruser@server/queue where
# ruser is the name of remote user, server is the host and queue is the
# print queue name as it would get passed to lpr -P queue.

# This backend is not secure! Its input is not validated, and could
# result in arbitrary shell commands being run as the lp user. See
# - http://www.cups.org/documentation.php/doc-1.7/api-filter.html#SECURITY
# - http://www.cups.org/documentation.php/doc-1.7/api-filter.html#PERMISSIONS
#
# The input could be validated in the style of the ./lpr-shell.sh
# script.

# ################################################################

# Messages appear in
#
#   tail -f /var/log/cups/error_log
#
# See http://www.cups.org/documentation.php/api-filter.html#MESSAGES
#
# On the x60s, the following test shows that we see ERROR, ALERT, and
# WARNING messages with the default CUPS log settings.

# for level in NOTICE INFO ERROR ALERT WARNING; do
#   echo "$level: Do we see messages of level $level?" >&2
# done
# echo "Do we see messages with no level?" >&2

function log {
    echo "ALERT: SSHLPR: $@" >&2
}

# EXIT code 5 tells the schedular to cancel the job:
# http://www.cups.org/documentation.php/doc-1.7/man-backend.html
#
# This has the added of bonus of making the schedular dump a huge
# amount of helpful debugging info into the log file. In other words,
# if we exit this way, there's no need for 'log'.
function fail {
    echo "ERROR: SSHLPR: $@" >&2
    exit 5
}

# With no parameters, we need to tell CUPS what we are.
if [ $# -le 0 ]
then
	echo "network sshlpr \"Unknown\" \"LPR thorugh SSH\""
	exit 0
fi

# Refuse to run as root.
if [ `whoami` != lp ]; then
  fail "Fix sshlpr file permissions (0555)."
fi

# If we get the correct number of arguments, as per:
# 	$1=job-id $2=user $3=title $4=copies $5=options $6=[file]
[ $# -lt 5 -o $# -gt 6 ] && fail "Bad arguments"

# Parse URL
#user=$2

[ -z "$DEVICE_URI" ] && fail "No device URI"

userserver="`echo $DEVICE_URI | cut -f 3 -d /`"
printer="`echo $DEVICE_URI | cut -f 4 -d /`"
if echo $userserver | grep -q '@'
then
	user="`echo $userserver | cut -f 1 -d '@' `"
	server="`echo $userserver | cut -f 2 -d '@' `"
else
  fail "Bad URI: no remote user specified"
fi

# Build options by prefixing them with '-o '.
options="-o $(echo "$5" | sed -re 's/ / -o /g')"

# See the file that cups wants to print:

# cat $6 > /tmp/file.ps
# chmod a+r /tmp/file.ps

# fail "Debug"

log "ssh -q ${user}@$server lpr $options -P $printer -#$4"

# This is a little tricky: if $6 is empty then we will be catting
# stdin, otherwise the specified file.
#
# The -o options mean we don't have to manually login as the lp
# user once before printing will work. Details:
#
#   http://linuxcommando.blogspot.com/2008/10/how-to-disable-ssh-host-key-checking.html
#
# Ugh: store the output of the ssh command in 'ssh_out' and include it
# in the error message on failure.
ssh_out="$(
cat $6 | ssh -q \
             -o UserKnownHostsFile=/dev/null \
             -o StrictHostKeyChecking=no \
             ${user}@$server \
             lpr $options -P $printer -#$4 \
             2>&1
)" || fail "Could not SSH: $ssh_out"
# Root version:
#cat $6 | su $localuser -c "ssh -i /home/collins/.ssh/keys-to-not-try-automatically/id_rsa_linuxlab_print -q ${user}@$server lpr $options -P $printer -#$4" || fail "Could not SSH"
log "Success!"
exit 0
